import java.util.Arrays;

interface IShape {   //通过interface定义接口,接口名一般以大写i开头
    int a=1;   //接口的成员变量默认是public static final的，所以必须要就地初始化
    //接口当中不存在构造方法，因为成员变量是final的，所以已经初始化完成了
    void shape();

    default void func() {        //接口当中一般不存在有方法体的方法，但是通过default和static修饰的方法，可以存在方法体
        System.out.println("haha");
    }
    static void func2() {
        System.out.println("hehe");
    }
}
class Rect1 implements IShape {    //通过implements关键字使得接口被类实现
    //因为接口中的方法是抽象方法，所以需要重写
    @Override
    public void shape() {
        System.out.println("矩形!");
    }
}
class Flowers implements IShape {
    @Override
    public void shape() {
        System.out.println("❀!");
    }
}

interface IUsb {
    void openDevice();
    void closeDevice();
}
interface IA {
    void funcA();
}
interface IB {
    void funB();
}
//c这个接口不仅具有func的功能还有funA和funB的功能，所以在实现c接口的时候要重写三个方法
interface C extends IA,IB{
    void funC();
}
class Mouse implements IUsb {
    @Override
    public void openDevice() {   //因为是接口，所以继承的类中需要重写抽象方法
        System.out.println("打开鼠标服务");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标服务");
    }
    public void click() {
        System.out.println("敲击键盘");
    }
}
class Keybord implements IUsb {
    @Override
    public void openDevice() {
        System.out.println("打开键盘");
    }

    @Override
    public void closeDevice() {
        System.out.println("关闭键盘");
    }

    public void inPut() {
        System.out.println("敲击键盘");
    }
}
class Computer {
    public void open() {
        System.out.println("开机");
    }
    public void close() {
        System.out.println("关机");
    }
    //所有usb接口都可以在电脑上使用
    public void useDevice(IUsb usb) {
        usb.openDevice();
        if(usb instanceof Mouse) {         //左边是对象，右边是类；当对象是右边类或子类所创建对象时，返回true；否则，返回false
            Mouse mouse=(Mouse)usb;
            mouse.click();//*这里发生了向下转型，目的是为了能够访问子类的方法，像这种用接口引用对象和通过父类引用子类的对象都是只能使用引用访问重写的方法
        }else if(usb instanceof Keybord) {
            Keybord keybord=(Keybord) usb;  //这里发生了向下转型
            keybord.inPut();
        }
        usb.closeDevice();
    }
}
public class JavaInterface {
    public static void main1(String[] args) {
        Computer computer=new Computer();
        Mouse mouse=new Mouse();
        Keybord keybord=new Keybord();
        computer.useDevice(new Mouse());
        computer.useDevice(keybord);
    }
    public static void drawMap(IShape iShape) {
        iShape.shape();
    }
    public static void main2(String[] args) {
        IShape iShape=new Rect1();  //接口不可以被实例化  如:IShape ishape=new IShape();
        drawMap(new Rect1());
        drawMap(new Flowers());
        Rect1 rect=new Rect1();
        Flowers flowers=new Flowers();
        IShape[] iShapes={rect,flowers};
        for (IShape iShape1:iShapes) {
            iShape1.shape();
        }
    }

    public static void mysort(Comparable[] array) { //这里使用接口类型来接收一个引用是因为teacher这个类实现了compare这个接口
        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j].compareTo(array[j+1])>0) {
                    Comparable tmp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=tmp;
                }
            }
        }
    }
    //exercise  比较teacher数组中的元素
    public static void main3(String[] args) {
       Teacher[] teacher={new Teacher("张三",35),new Teacher("李四",28),new Teacher("王五",45)};
        System.out.println(teacher[0].compareTo(teacher[1]));   //这样传的话那么compareto的this就是teacher【0】，因为this是对象的引用
        //Arrays.sort(teacher);   //在排序的时候每个元素都会被强转为comparable
        mysort(teacher);
       System.out.println(Arrays.toString(teacher));
    }
}
class Teacher implements Comparable<Teacher>{   //接口comparable中存在抽象方法compaTo
    public String name;
    public int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Teacher o) {   //这样写非常的不灵活
        //1.通过age进行比较
//        if(this.age>o.age) {
//            return 1;
//        }if(this.age<o.age) {
//            return -1;
//        }else {
//            return 0;
//        }
        //2.通过name进行比较 这里的compato是字符串的比较
        if(this.name.compareTo(o.name)>0) {
            return 1;
        }else if(this.name.compareTo(o.name)<0) {
            return -1;
        }else {
            return 0;
        }
    }
}
